package net.danielthompson.danray.shapes;

import net.danielthompson.danray.shading.Material;
import net.danielthompson.danray.states.IntersectionState;
import net.danielthompson.danray.structures.BoundingBox;
import net.danielthompson.danray.structures.Point;
import net.danielthompson.danray.structures.Vector;

import static net.danielthompson.danray.structures.Constants.WithinDelta;

/**
 * DanRay
 * User: dthompson
 * Date: 7/8/13
 * Time: 1:10 PM
 */
public class ImplicitPlane implements Drawable {
   private Point _origin;
   private Vector _normal;

   private Material _material;

   public ImplicitPlane(Point origin, Vector normal, Material material) {
      _origin = origin;
      _normal = normal;
      _material = material;
   }

   @Override
   public Material GetMaterial() {
      return _material;
   }

   public Vector GetNormal() {
      return _normal;
   }

   @Override
   public IntersectionState GetHitInfo(Vector vector) {
      double numerator = (Point.Minus(_origin, vector.Origin)).Dot(_normal.Direction);
      double denominator = vector.Direction.Dot(_normal.Direction);

      IntersectionState state = new IntersectionState();
      state.Drawable = this;

      if (WithinDelta(denominator, 0.0)) {
         // no intersection
         state.Hits = false;
      }
      else {
         double T = numerator / denominator;
         if (T > 0.0) {
            state.Hits = true;
            state.T = T;
            state.IntersectionPoint = Point.Plus(vector.Scale(state.T), vector.Origin);
            state.Normal = _normal;
         }
      }

      return state;
   }

   public boolean On(Point p) {
      return (_normal.Direction.Dot(Point.Minus(_origin, p)) == 0);
   }

   @Override
   public double BRDF(IntersectionState state, Vector cameraRay, Vector lightRay) {
      return 0;
   }

   @Override
   public double GetVolume() {
      return 0;
   }

   @Override
   public BoundingBox GetBoundingBox() {
      return null;
   }
}
